class Counter:
    def __init__(self):
        self.count = 0

    def __wrap_f(self, f, x):
        self.count += 1
        return f(x)

    def wrap(self, f):
        return lambda x: self.__wrap_f(f, x)


def wrap(f, g, h):
    """
    Generate function call counters

    :param f: objective function
    :param g: gradient
    :param h: hessian
    :return: wrapped f,g,G and corresponding counters
    """
    fc = Counter()
    gc = Counter()
    hc = Counter()
    return fc.wrap(f), gc.wrap(g), hc.wrap(h), fc, gc, hc
